#ifndef CACHE_FILE_H
#define CACHE_FILE_H
#include "common.h"
#include "queue.h"


typedef char cache_key;

enum cache_status {
	CACHE_NONE = -1,  /* can not store in the cache */
	CACHE_DOWNLOADING, /* downloading now */
	CACHE_DOWNLOAD_FAILED, 
	CACHE_IN_DISK,   /* download completely, and swap out to disk */
	CACHE_IN_FRESH,
	CACHE_IN_STALE,
};


typedef struct cache_time {
	time_t freshness_lifetime; 
	time_t age; /* two time above are very important */
	time_t response_got;
	time_t request_issued;
	time_t expires;
	time_t date;
	time_t last_modified;
	time_t max_age;
	time_t header_age;
}cache_time_t;

typedef struct {
	aint high;
	aint low;
	char *buf;
	int offset;   /* data room */
	int size;    /* size == memin_high - memin_low */
}mem_t;

typedef struct {
	aint high;
	aint low;
	aint size;
	int fd;
}shm_t;

typedef struct {
	aint body_size;
	aint header_size;
	int ref;
	int statu;
	int dir_no;
	int should_free;
	cache_time_t time;
	unsigned char key[16];
	char *human_key;
	
	string *file;       /* full path */
	mem_t *mem_cache;
	shm_t *shm_cache;

	pthread_mutex_t lock; /* lock ref */
}cache_file_t;

extern void cache_file_table_init(void);
extern void cache_file_table_clean(void);
extern int cache_file_insert(cache_file_t *cache);
extern cache_file_t *cache_file_search(const char *url, const int size);
extern cache_file_t *cache_ref(cache_file_t *cache);
extern void cache_unref(cache_file_t *cache);
extern cache_file_t *cache_file_create(const char *url);
extern cache_file_t *cache_file_delete(cache_file_t *cache);
extern void cache_file_destroy(cache_file_t *cache);
extern void cache_file_del(cache_file_t *cache);
extern void cache_file_delete_and_free(cache_file_t *cache);	
extern void cache_file_free(cache_file_t *cache);
extern char *cache_statu(int statu);
extern int cache_lock(cache_file_t *cache);
extern int cache_unlock(cache_file_t *cache);
extern void cache_file_reset(cache_file_t *cache);
#endif
